package org.xxpay.pay.channel.ymkjpay;

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.domain.api.AbstractRes;
import org.xxpay.core.common.domain.api.ApiBuilder;
import org.xxpay.core.common.domain.api.PayRes;
import org.xxpay.core.common.domain.api.msg.QueryRetMsg;
import org.xxpay.core.common.util.AmountUtil;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.XXPayUtil;
import org.xxpay.core.common.vo.DBApplicationConfig;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;

import java.util.HashMap;
import java.util.Map;

@Service
public class YmkjpayPaymentService extends BasePayment {
    private static final MyLog _log = MyLog.getLog(YmkjpayPaymentService.class);

    @Override
    public String getChannelName() {
        return YmkjpayConfig.CHANNEL_NAME;
    }

    /**
     * 支付
     * @param payOrder
     * @return
     */
    @Override
    public AbstractRes pay(PayOrder payOrder) {
        String channelId = payOrder.getChannelId();
        AbstractRes retObj;
        switch (channelId) {
            case YmkjpayConfig.CHANNEL_NAME_WECHAT :
                retObj = doPayReq(payOrder, YmkjpayConfig.CHANNEL_TYPE_WECHAT);
                break;
            case YmkjpayConfig.CHANNEL_NAME_WECHAT_H5 :
                retObj = doPayReq(payOrder, YmkjpayConfig.CHANNEL_TYPE_WECHAT);
                break;
            case YmkjpayConfig.CHANNEL_NAME_ALIPAY :
                retObj = doPayReq(payOrder, YmkjpayConfig.CHANNEL_TYPE_ALIPAY);
                break;
            case YmkjpayConfig.CHANNEL_NAME_ALIPAY_H5 :
                retObj = doPayReq(payOrder, YmkjpayConfig.CHANNEL_TYPE_ALIPAY);
                break;
            default:
                return ApiBuilder.bizError("不支持的渠道[channelId="+channelId+"]");
        }
        return retObj;
    }
    /**
     * 优术科技
     * @param payOrder
     * @return
     */
    public AbstractRes doPayReq(PayOrder payOrder, String payType) {
        String logPrefix = "【优术支付】";
        YmkjpayConfig ymkjPayConfig = new YmkjpayConfig(getPayParam(payOrder));
        PayRes retObj = ApiBuilder.buildSuccess(PayRes.class);
        try {
            //服务端参数拼写
            String reqUrl = ymkjPayConfig.getReqUrl();//提交地址
            String payUrl = reqUrl + "/api/orders/index.html";
            if (reqUrl.endsWith("/")) {
                payUrl = reqUrl + "api/orders/index.html";
            }
            DBApplicationConfig dbConfig = getDBApplicationConfig();
            String mch_id = ymkjPayConfig.getMchId();//商户号
            String key = ymkjPayConfig.getKey();//密钥
            Map paramMap = new HashMap();
            paramMap.put("mch_id", mch_id);//平台分配商户号
            paramMap.put("price", AmountUtil.convertCent2Dollar(String.valueOf(payOrder.getAmount())));//订单金额
            paramMap.put("out_order_id", payOrder.getPayOrderId());//订单号
            paramMap.put("type", payType);//支付类型
            paramMap.put("returnurl", payOrder.getReturnUrl()==null ? super.getReturnUrl(getChannelName(), dbConfig) : payOrder.getReturnUrl());//同步消息返回地址
            paramMap.put("notifyurl", super.getNotifyUrl(getChannelName(), dbConfig));//异步消息通知Url

            //加密参数按参数名的字母顺序排列，从key1=value1&key2=value2&...&keyN=valueN,值为空的不参与验签，最后加上密钥：key，进行MD5加密，加密后的值大写
            String sign = ymkjPayConfig.getSign(paramMap, key);
            paramMap.put("sign", sign);
            _log.info("{}请求地址:{}",logPrefix,payUrl);
            String reqData = XXPayUtil.genUrlParams(paramMap);
            _log.info("[{}]请求数据:{}", getChannelName(), reqData);
            String result = XXPayUtil.call4Post(payUrl+"?" + reqData);
            _log.info("{}请求结果:{}",logPrefix,result);
            JSONObject params = JSONObject.parseObject(result);
            if ((params.getInteger("code")) == 1){
                String data = params.getString("data");
                JSONObject dataParams = JSONObject.parseObject(data);
                String payJumpUrl = dataParams.getString("pay_url");
                // 支付链接地址
                StringBuffer payForm = new StringBuffer();
                payForm.append("<form style=\"display: none\" action=\""+payJumpUrl+"\" method=\"post\">");
                payForm.append("<input type=\"submit\" value=\"立即支付\" style=\"display:none\" >");
                payForm.append("</form>");
                payForm.append("<script>document.forms[0].submit();</script>");
                retObj.setPayMethod(PayConstant.PAY_METHOD_FORM_JUMP);
                retObj.setPayUrl(payForm.toString());
                retObj.setPayJumpUrl(payJumpUrl);
                int updateCount = commonService.payOrderService.updateStatus4Ing(payOrder.getPayOrderId(), null);
                _log.info("[{}]更新订单状态为支付中:payOrderId={},payUrl={},result={}", getChannelName(), payOrder.getPayOrderId(), payUrl, updateCount);
                return retObj;
            }else {
                String msg = params.toJSONString();
                return ApiBuilder.bizError("调起通道失败[通道提示：" + msg +"]");
            }
        }catch (Exception e){
            _log.error(e, "");
            return ApiBuilder.bizError("操作失败!");
        }
    }

    /**
     * 查询订单
     * @param payOrder
     * @return
     */
    @Override
    public QueryRetMsg query(PayOrder payOrder) {
        String logPrefix = "【优术支付】";
        YmkjpayConfig ymkjPayConfig = new YmkjpayConfig(getPayParam(payOrder));
        Map<String, Object> map = new HashMap<>();
        // 商户ID
        map.put("mch_id", ymkjPayConfig.getMchId());
        // 商户订单号
        map.put("order_sn", payOrder.getPayOrderId());

        String key = ymkjPayConfig.getKey();
        String reqUrl = ymkjPayConfig.getReqUrl();
        String queryUrl = reqUrl + "/api/orders/query.html";
        if (reqUrl.endsWith("/")) {
            queryUrl = reqUrl + "api/orders/query.html";
        }
        _log.info("{}请求地址:{}",logPrefix,reqUrl);
        String reqData = XXPayUtil.genUrlParams(map);
        _log.info("[{}]请求数据:{}", getChannelName(), reqData);
        String result = XXPayUtil.call4Post(queryUrl+"?" + reqData);
        _log.info("{}请求结果:{}",logPrefix,result);

        JSONObject params = JSONObject.parseObject(result);
        // 交易状态:   交易状态码（0=未支付,1=已过期,2=已支付,未通知,3=通知失败,4=已完成,5=已冻结)
        int code = (int) params.get("code");
        if (code == 1){
            JSONObject data = (JSONObject) params.get("data");
            String state = (String) data.get("status");
            if("2".equals(state) || "3".equals(state) || "4".equals(state)){
                return QueryRetMsg.confirmSuccess(null);  // 成功
            }else {
                return QueryRetMsg.waiting();  //支付中
            }
        } else {
            return QueryRetMsg.waiting();  //支付中
        }
    }

}
